package cn.oowoo.jsr303.controller;

import cn.oowoo.jsr303.common.dto.JSR303Dto;
import cn.oowoo.jsr303.common.dto.JSR303TestDto;
import cn.oowoo.jsr303.common.result.Result;
import cn.oowoo.jsr303.common.util.ValidateUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * 1、分组
 *  @Validated：提供了一个分组功能，可以在入参验证时，根据不同的分组采用不同的验证机制，这个网上也有资料，不详述。
 *  @Valid：作为标准JSR-303规范，还没有吸收分组的功能
 *
 * 2、注解的地方
 *  @Validated：可以用在类型、方法和方法参数上。但是不能用在成员属性（字段）上
 *  @Valid：可以用在方法、构造函数、方法参数和成员属性（字段）上
 *
 * 3、嵌套验证
 *  @Validated：用在方法入参上无法单独提供嵌套验证功能。不能用在成员属性（字段）上，也无法提示框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。
 *  @Valid：用在方法入参上无法单独提供嵌套验证功能。能够用在成员属性（字段）上，提示验证框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。
 *
 * 作者：花郎徒结
 * 来源：CSDN
 * 原文：https://blog.csdn.net/qq_27680317/article/details/79970590
 * 版权声明：本文为博主原创文章，转载请附上博文链接！
 */
@Slf4j
@RequestMapping("JSR-303")
@RestController
public class JSR303TestController {
    /**
     * @Author: zhangbin
     * @Date: 2019/4/23 14:16
     * @Return
     * @Description:添加实体类，采用JSR303Dto.Add.class组来做校验
     *
     */
    @RequestMapping("add")
    public Result add(@Validated({JSR303Dto.Add.class}) @RequestBody JSR303Dto jsr303Dto, BindingResult bindingResult){
        log.info("START-jsr303Dto:{}", JSON.toJSONString(jsr303Dto));
        Result validate = ValidateUtil.validate(bindingResult);
        if(validate != null){
            return validate;
        }
        return Result.success("校验通过!");
    }
    /**
     * @Author: zhangbin
     * @Date: 2019/4/23 14:16
     * @Return
     * @Description:更新实体类，采用JSR303Dto.Update.class组来做校验
     *
     */
    @RequestMapping("update")
    public Result update(@Validated(JSR303Dto.Update.class) @RequestBody JSR303Dto jsr303Dto, BindingResult bindingResult){
        log.info("START-jsr303Dto:{}",JSON.toJSONString(jsr303Dto));
        Result validate = ValidateUtil.validate(bindingResult);
        if(validate != null){
            return validate;
        }
        return Result.success("校验通过!");
    }
    /**
     * @Author: zhangbin
     * @Date: 2019/4/23 14:16
     * @Return
     * @Description:不使用分组测试
     *
     */
    @RequestMapping("normalCheck")
    public String normalCheck(@Validated @RequestBody JSR303TestDto jsr303TestDto, BindingResult bindingResult){
        log.info("START-jsr303Dto:{}",JSON.toJSONString(jsr303TestDto));
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        List<String> errorResult = new ArrayList<>();
        allErrors.forEach(x->{
            FieldError error = (FieldError)x;
            String err =   error.getField() + " : " + error.getDefaultMessage();
            log.info(err);
            errorResult.add(err);
        });
        return JSON.toJSONString(errorResult);
    }
}
